package com.wwdeng.print.app.printer

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import com.wwdeng.print.app.PrintApp
import com.wwdeng.print.app.R
import com.wwdeng.print.app.printer.PrintHelper.formatPrintInvoice
import net.posprinter.utils.BitmapProcess
import net.posprinter.utils.BitmapToByteData
import net.posprinter.utils.DataForSendToPrinterPos80
import org.json.JSONObject
import java.io.ByteArrayOutputStream
import java.math.BigDecimal


/**
 * PrintTestDemo
 * @Author：wwdeng
 * @CreateTime：2025/4/13 18:10
 * <pre>
 *  打印帮助类
 * </pre>
 */
object PrintHelper {

    /**
     * 预结单、结账单、发票
     * 头部：LOGO，描述、店铺名称
     */
    fun MutableList<ByteArray>.getPrintStoreTop(obj: JSONObject): MutableList<ByteArray>{
        apply {
            // 初始化打印机
            add(EscPosUtils.initPrinter())
            // 设置居中对齐
            add(EscPosUtils.setAlign(1))
            
            //logo
//            var logoResId = obj.optInt("logoResId",0)
//            if (logoResId == 0){
//                logoResId = R.mipmap.test_logo
//            }
//            val bitmap = BitmapProcess.compressBmpByYourWidth(BitmapFactory.decodeResource(PrintApp.app.resources, logoResId), 300)
//            val bList = BitmapProcess.cutBitmap(150,bitmap)
//            for (i in bList.indices) {
//                add(DataForSendToPrinterPos80.printRasterBmp(0, bList[i], BitmapToByteData.BmpType.Dithering, BitmapToByteData.AlignType.Center, 576))
//            }

            //logo
            var logoBitmap = BitmapProcess.compressBmpByYourWidth(BitmapFactory.decodeResource(PrintApp.app.resources, R.mipmap.test_logo), 300)
            val logoPath = obj.optString("logoLocalPath","")
            if (logoPath.isNotEmpty()){
                logoBitmap = BitmapLoader.loadBitmap(logoPath)
            }
            if (logoBitmap != null){
                val bList = BitmapProcess.cutBitmap(150,logoBitmap)
                for (i in bList.indices) {
                    add(DataForSendToPrinterPos80.printRasterBmp(0, bList[i], BitmapToByteData.BmpType.Dithering, BitmapToByteData.AlignType.Center, 576))
                }
            }

            //设置行间距
            add(EscPosUtils.setLineSpacing(80))

            //店铺描述
            add(EscPosUtils.printLine("★${obj.optString("storeDesc")}★"))

            //店名
            add(EscPosUtils.setFontSize(17))
            add(EscPosUtils.setBold(true))
            add(EscPosUtils.setLineSpacing(120))
            add(EscPosUtils.printLine(obj.optString("storeTitle")))
            add(EscPosUtils.setBold(false))
            add(EscPosUtils.setFontSize(0))
        }
        return this
    }


    /**
     * 商品列表
     */
    fun MutableList<ByteArray>.getPrintProductList(obj: JSONObject): MutableList<ByteArray>{
        apply {
            //设置行间距
            add(EscPosUtils.setLineSpacing(80))
            // 设置居中对齐
            add(EscPosUtils.setAlign(1))
            // 设置字体大小
            add(EscPosUtils.setFontSize(0))

            val menuList = obj.optJSONArray("menuList")
            var totalPrice = 0
            var totalNum = 0
            if (menuList != null) {
                for (i in 0..< menuList.length()){
                    val item = menuList.optJSONObject(i)
//                        //左对齐
//                        add(EscPosUtils.setAlign(0))
//                        //菜名字
//                        add(EscPosUtils.printLine(item.optString("title")))
//                        //右对齐
//                        add(EscPosUtils.setAlign(2))
                    //单价x数量=总价
                    val price = BigDecimal(item.optString("price")).stripTrailingZeros().toPlainString()
                    val num = BigDecimal(item.optString("num")).stripTrailingZeros().toPlainString().toInt()
                    val total = BigDecimal(price).multiply(BigDecimal("$num")).stripTrailingZeros().toPlainString().toInt()
                    totalPrice += total
                    totalNum += num
//                        add(EscPosUtils.printLine("￥$price${"x"}$num=￥$total"))
                    add(EscPosUtils.printTwoColumns(item.optString("title"),"￥$price${"x"}$num=￥$total",48))
                }
            }
        }
        return this
    }


    /**
     * 预结单
     */
    fun MutableList<ByteArray>.formatPrintPreSettlementOrder(order: JSONObject): MutableList<ByteArray>{
        apply {
            //logo、描述、店铺名称
            getPrintStoreTop(order)

            // 设置居中对齐
            add(EscPosUtils.setAlign(1))
            // 设置字体大小
            add(EscPosUtils.setFontSize(0))
            //创建时间
            add(EscPosUtils.printLine(order.optString("createTime")))
            //设置行间距
            add(EscPosUtils.setLineSpacing(80))
            //座位号
            add(EscPosUtils.printLine("席番号：${order.optString("tableCode")}(${order.optString("count")}名)"))

            //多换一行
            add(EscPosUtils.lineFeed())

            //分割线
            add(EscPosUtils.printDivider('-', 48))

            //商品列表
            getPrintProductList(order)
            val totalNum = order.optString("totalNum")
            val totalPrice = order.optString("totalPrice")

            // 设置居中对齐
            add(EscPosUtils.setAlign(1))
            //分割线
            add(EscPosUtils.printDivider('-', 48))
            //商品总数
            add(EscPosUtils.printTwoColumns("商品点数","${totalNum}点",48))
            //商品合计
            add(EscPosUtils.printTwoColumns("商品合計(税込)","￥${totalPrice}",48))

            // 设置右对齐
            add(EscPosUtils.setAlign(2))
            //税率
            add(EscPosUtils.printLine("*は軽減税率8%適用商品"))

            // 设置居中对齐
            add(EscPosUtils.setAlign(1))
            //税后小计
            add(EscPosUtils.printTwoColumns("小計(税抜)","￥${totalPrice.toInt() - (totalPrice.toInt() * 0.08)}",48))
            //消费税
            add(EscPosUtils.printTwoColumns("消費税","￥${totalPrice.toInt() * 0.08}",48))

            //合计
            add(EscPosUtils.setFontSize(17))
            add(EscPosUtils.printTwoColumns("合計","￥$totalPrice",48))
            add(EscPosUtils.setFontSize(0))

            // 设置右对齐
            add(EscPosUtils.setAlign(2))
            add(EscPosUtils.printLine("(8%対象  ￥$totalPrice)"))
            add(EscPosUtils.printLine("(10%对象  ￥0)"))

            // 设置居中对齐
            add(EscPosUtils.setAlign(1))
            //支付方式
            add(EscPosUtils.printTwoColumns("PayPay","￥$totalPrice",48))
            add(EscPosUtils.printTwoColumns("お釣り","￥0",48))
            //分割线
            add(EscPosUtils.printDivider('-', 48))

            // 设置左对齐
            add(EscPosUtils.setAlign(0))
            //登录番号
            add(EscPosUtils.printLine("登録番号：${order.optString("loginCode")}"))
            //姓名
            add(EscPosUtils.printLine("事業者名：${order.optString("loginName")}"))
            //地址
            add(EscPosUtils.printLine(order.optString("address")))
            //电话
            add(EscPosUtils.printLine(order.optString("mobile")))
        }
        return this
    }

    /**
     * 结账单
     */
    fun MutableList<ByteArray>.formatPrintSettlementOrder(order: JSONObject): MutableList<ByteArray>{
        apply {
            //logo、描述、店铺名称
            getPrintStoreTop(order)

            // 设置居中对齐
            add(EscPosUtils.setAlign(1))
            // 设置字体大小
            add(EscPosUtils.setFontSize(0))
            //分割线
            add(EscPosUtils.setLineSpacing(80))
            add(EscPosUtils.printDivider('*', 48))
            add(EscPosUtils.setFontSize(17))
            add(EscPosUtils.setLineSpacing(120))
            add(EscPosUtils.printLine("会計前伝票"))
            add(EscPosUtils.setFontSize(0))
            add(EscPosUtils.setLineSpacing(80))
            //分割线
            add(EscPosUtils.printDivider('*', 48))

            //创建时间
            add(EscPosUtils.printLine(order.optString("createTime")))

            //座位号
            add(EscPosUtils.printLine("席番号：${order.optString("tableCode")}(${order.optString("count")}名)"))

            //分割线
            add(EscPosUtils.printDivider('-', 48))

            //商品列表
            getPrintProductList(order)
            val totalNum = order.optString("totalNum")
            val totalPrice = order.optString("totalPrice")

            // 设置居中对齐
            add(EscPosUtils.setAlign(1))
            // 设置字体大小
            add(EscPosUtils.setFontSize(0))
            //分割线
            add(EscPosUtils.printDivider('-', 48))
            //商品总数
            add(EscPosUtils.printTwoColumns("商品点数","${totalNum}点",48))
            //商品合计
            add(EscPosUtils.printTwoColumns("商品合計(税込)","￥$totalPrice",48))

            // 设置右对齐
            add(EscPosUtils.setAlign(1))
            //税率
            add(EscPosUtils.printLine("*は軽減税率8%適用商品"))

            //税后小计
            add(EscPosUtils.printTwoColumns("小計(税抜)","￥${totalPrice.toInt() - (totalPrice.toInt() * 0.08)}",48))
            //值引金額
            add(EscPosUtils.printTwoColumns("值引金額","-0",48))
            //消费税
            add(EscPosUtils.printTwoColumns("消費税","￥${totalPrice.toInt() * 0.08}",48))

            //合计
            add(EscPosUtils.setFontSize(17))
            add(EscPosUtils.setBold(true))
            add(EscPosUtils.printTwoColumns("合計","￥$totalPrice",48))
            add(EscPosUtils.setFontSize(0))
            add(EscPosUtils.setBold(false))

            // 设置右对齐
            add(EscPosUtils.setAlign(2))
            add(EscPosUtils.printLine("(8%対象  ￥$totalPrice)"))
            add(EscPosUtils.printLine("(10%对象  ￥0)"))

            // 设置居中对齐
            add(EscPosUtils.setAlign(1))
            //分割线
            add(EscPosUtils.printDivider('-', 48))

            // 设置左对齐
            add(EscPosUtils.setAlign(0))
            //登录番号
            add(EscPosUtils.printLine("登録番号：${order.optString("loginCode")}"))
            //地址
            add(EscPosUtils.printLine(order.optString("address")))
            //电话
            add(EscPosUtils.printLine(order.optString("mobile")))

            // 设置居中对齐
            add(EscPosUtils.setAlign(1))
            //二维码
            add(EscPosUtils.printQRCode(order.optString("qrCodeUrl"), 6, 48));
        }
        return this
    }

    /**
     * 发票
     */
    fun MutableList<ByteArray>.formatPrintInvoice(order: JSONObject): MutableList<ByteArray>{
        apply {
            //logo、描述、店铺名称
            getPrintStoreTop(order)

            // 设置居中对齐
            add(EscPosUtils.setAlign(1))

            //領收書
            add(EscPosUtils.setFontSize(17))
            add(EscPosUtils.setLineSpacing(120))
            add(EscPosUtils.printLine("領 收 書"))
            add(EscPosUtils.setFontSize(0))
            //创建时间
            add(EscPosUtils.printLine(order.optString("createTime")))
            //设置行间距
            add(EscPosUtils.setLineSpacing(80))
            // 设置居右对齐
            add(EscPosUtils.setAlign(2))
            add(EscPosUtils.printLine("様"))

            // 设置居中对齐
            add(EscPosUtils.setAlign(1))
            //分割线
            add(EscPosUtils.setBold(true))
            add(EscPosUtils.printDivider('-', 48))
            add(EscPosUtils.setBold(false))
            // 设置居右对齐
            add(EscPosUtils.setAlign(2))
            add(EscPosUtils.setFontSize(17))
            add(EscPosUtils.printLine("￥${order.optString("totalPrice")}-"))
            add(EscPosUtils.setFontSize(0))

            // 设置居中对齐
            add(EscPosUtils.setAlign(1))

            //分割线
            add(EscPosUtils.setBold(true))
            add(EscPosUtils.printDivider('-', 48))
            add(EscPosUtils.setBold(false))

            // 设置居右对齐
            add(EscPosUtils.setAlign(2))
            add(EscPosUtils.printLine("(内消費税：￥${order.optString("tax")})"))
            add(EscPosUtils.printLine("8%対象：￥0-)"))
            add(EscPosUtils.printLine("10%対象：￥${order.optString("totalPrice")}-"))

            // 设置居中对齐
            add(EscPosUtils.setAlign(1))
            add(EscPosUtils.printTwoColumns("开票人",order.optString("userName"),48))

            // 设置靠左对齐
            add(EscPosUtils.setAlign(0))
            add(EscPosUtils.printLine("但し 飲食代として"))
            add(EscPosUtils.printLine("上記正に領収いたしました。"))

            // 设置居中对齐
            add(EscPosUtils.setAlign(1))
            add(EscPosUtils.printDivider('-', 48))
            add(EscPosUtils.printLine("*領收書明細*"))

            //商品列表
            getPrintProductList(order)
            val totalPrice = order.optString("totalPrice")

            //合计
            add(EscPosUtils.printTwoColumns("合計","￥$totalPrice",48))

            // 设置左对齐
            add(EscPosUtils.setAlign(0))
            //登录番号
            add(EscPosUtils.printLine("登録番号：${order.optString("loginCode")}"))
            //姓名
            add(EscPosUtils.printLine("事業者名：${order.optString("loginName")}"))
            //地址
            add(EscPosUtils.printLine(order.optString("address")))
            //电话
            add(EscPosUtils.printLine(order.optString("mobile")))
        }
        return this
    }

    /**
     * 后厨单
     */
    fun MutableList<ByteArray>.formatPrintKitchen(order: JSONObject): MutableList<ByteArray> {
        apply {
            // 初始化打印机
            add(EscPosUtils.initPrinter())
            //设置行间距
            add(EscPosUtils.setLineSpacing(80))
            // 设置居中对齐
            add(EscPosUtils.setAlign(1))
            add(EscPosUtils.printTwoColumns(order.optString("createTime"),"席番号：${order.optString("tableCode")}",48))

            //菜品列表
            val menuList = order.optJSONArray("menuList")
            val leftList = arrayListOf<String>()
            val rightList = arrayListOf<String>()
            menuList?.let {
                for (i in 0..< it.length()){
                    val item = it.optJSONObject(i)
                    leftList.add(item.optString("price"))
                    rightList.add("${item.optString("title")} ${item.optString("num")}個")
                }
            }
            add(EscPosUtils.generateDoubleSizeColumns(leftList,rightList))

            // 设置靠右对齐
            add(EscPosUtils.setAlign(2))
            add(EscPosUtils.printLine("担当者：${order.optString("userCode")}"))
        }
        return this
    }

    /**
     * 交班单
     */
    fun MutableList<ByteArray>.formatPrintHandover(order: JSONObject): MutableList<ByteArray> {
        apply {
            // 初始化打印机
            add(EscPosUtils.initPrinter())
            // 设置居中对齐
            add(EscPosUtils.setAlign(1))

            //logo
            var logoResId = order.optInt("logoResId",0)
            if (logoResId == 0){
                logoResId = R.mipmap.test_logo
            }
            val bitmap = BitmapProcess.compressBmpByYourWidth(BitmapFactory.decodeResource(PrintApp.app.resources, logoResId), 300)
            val bList = BitmapProcess.cutBitmap(150,bitmap)
            for (i in bList.indices) {
                add(DataForSendToPrinterPos80.printRasterBmp(0, bList[i], BitmapToByteData.BmpType.Dithering, BitmapToByteData.AlignType.Center, 576))
            }

            //店名
            add(EscPosUtils.setFontSize(17))
            add(EscPosUtils.setBold(true))
            add(EscPosUtils.setLineSpacing(120))
            add(EscPosUtils.printLine(order.optString("storeTitle")))
            add(EscPosUtils.setBold(false))
            add(EscPosUtils.setFontSize(0))

            //设置行间距
            add(EscPosUtils.setLineSpacing(80))
            // 设置居中对齐
            add(EscPosUtils.setAlign(1))

            //打印时间
            add(EscPosUtils.printTwoColumns(order.optString("createTime"),order.optString("operatorName"),48))

            //分割线
            add(EscPosUtils.printDivider('-', 48))
            //总点数
            add(EscPosUtils.printTwoColumns("总点数","675点",48))
            //商品合计
            add(EscPosUtils.printTwoColumns("商品合計（税拔）","￥230,111",48))
            //分割线
            add(EscPosUtils.printDivider('-', 48))

            //売上高
            add(EscPosUtils.printTwoColumns("売上高（税込）","￥253,122",48))

            //分割线
            add(EscPosUtils.printDivider('-', 48))
            //商品合计（三列）
            add(EscPosThreeColumnPrinter.generateThreeColumns("商品合計","53件","2531"))
            //分割线
            add(EscPosUtils.printDivider('-', 48))

            //値引金額
            add(EscPosUtils.printTwoColumns("値引金額","0",48))

            //分割线
            add(EscPosUtils.printDivider('-', 48))
            //現金値引
            add(EscPosUtils.printTwoColumns("現金値引","0",48))
            //クーポン値引
            add(EscPosUtils.printTwoColumns("クーポン値引","0",48))
            //端数値引
            add(EscPosUtils.printTwoColumns("端数値引","0",48))
            //分割线
            add(EscPosUtils.printDivider('-', 48))

            //合計
            add(EscPosUtils.printTwoColumns("合計","￥253,122",48))

            //（10%対象）
            add(EscPosUtils.printLine("10%対象）￥253122"))

            //内消費税
            add(EscPosUtils.printTwoColumns("内消費税","￥23,011",48))

            //合計（税抜）
            add(EscPosUtils.printTwoColumns("合計（税抜）","￥230,111",48))

            //分割线
            add(EscPosUtils.printDivider('-', 48))
            //今日合計
            add(EscPosUtils.printLine("今日合計"))
            //分割线
            add(EscPosUtils.printDivider('-', 48))

            //取引数
            add(EscPosUtils.printTwoColumns("取引数","51组",48))
            //客数
            add(EscPosUtils.printTwoColumns("客数","115人",48))
            //客単価
            add(EscPosUtils.printTwoColumns("客単価","￥2,201",48))

            //分割线
            add(EscPosUtils.printDivider('-', 48))
            //支払種別（税込）
            add(EscPosUtils.printLine("支払種別（税込）"))
            //分割线
            add(EscPosUtils.printDivider('-', 48))

            //現金
            add(EscPosUtils.printTwoColumns("現金","￥117,362",48))
            //QRコード
            add(EscPosUtils.printTwoColumns("QRコード","￥0",48))
            //三井POS
            add(EscPosUtils.printTwoColumns("三井POS","￥32,078",48))
            //ポイント
            add(EscPosUtils.printTwoColumns("ポイント","￥1,000",48))
            //レストランボード
            add(EscPosUtils.printTwoColumns("レストランボード","￥0",48))
            //会員カード
            add(EscPosUtils.printTwoColumns("会員カード","￥0",48))
            //コード決済
            add(EscPosUtils.printTwoColumns("コード決済","￥102,682",48))

            //分割线
            add(EscPosUtils.printDivider('-', 48))
            //合計
            add(EscPosUtils.printTwoColumns("合計","253,122",48))
//            add(EscPosDoubleBoldColumnPrinter.generateDoubleSizeLine("合計","253,122",false))
            //分割线
            add(EscPosUtils.printDivider('-', 48))

            //今月累計
            add(EscPosUtils.printLine("今月累計"))

            //分割线
            add(EscPosUtils.printDivider('-', 48))
            //売上
            add(EscPosUtils.printTwoColumns("売上","10,121,788",48))
            //組数
            add(EscPosUtils.printTwoColumns("組数","1445組",48))
            //人数
            add(EscPosUtils.printTwoColumns("人数","4660人",48))
            //客単価
            add(EscPosUtils.printTwoColumns("客単価","￥2,172",48))
            //印刷時間：
            add(EscPosUtils.printLine("印刷時間：${order.optString("createTime")}"))
        }
        return this
    }

}